React is a popular library for creating web apps and mobile apps.
In this article, we’ll look at some tips for writing better React apps.
Detecting User Leaving Page with React Router
React Router has the Prompt component to let us block navigation with a message.
For instance, we can write:
import { Prompt } from 'react-router'
const App = () => (
<React.Fragment>
<Prompt
when={shouldBlockNavigation}
message='Are you sure you want to leave?'
/>
{/* more components */}
</React.Fragment>
)
We have the Prompt which takes a when prompt with a boolean expression that indicates when we want to block navigation.
message is the message to display when the user tries to leave.
It’ll block anything but not page refresh or closing.
To block refresh or closing, we’ve to set the onbeforeunload property to different values depending on whether navigation is blocked or not.
For instance, we can write:
componentDidUpdate = () => {
if (shouldBlockNavigation) {
window.onbeforeunload = () => true
} else {
window.onbeforeunload = undefined
}
}
If navigation should be blocked when refreshing or closing the browser tab, then we set it window.onbeforeunload to a function that returns true .
Otherwise, we set it to undefined .
Avoid Extra Wrapping <div> in React
We can use a fragment to avoid wrapper an extra div outside our components.
For instance, we can write:
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
or:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}
Deal with a Fetch Error in react-redux
We can use redux-thunk to create an async action that calls dispatch to dispatch synchronous actions on error.
For instance, we can write:
export function getData() {
return dispatch => {
dispatch({type: FETCH });
httpClient.get('/data')
.then(res => {
dispatch({ type: FETCH_SUCCESS, data: res.body });
})
.catch(error => {
dispatch({type: FAILED });
dispatch({type: ADD_ERROR, error });
});
};
}
We have a thunk that gets data and calls dispatch to dispatch various actions.
In our errors reducer, we can write:
function errors(state = [], action) {
switch (action.type) {
case ADD_ERROR:
return [...state, action.error];
case REMOVE_ERROR:
return state.filter((error, i) => i !== action.index);
default:
return state;
}
}
We have the errors reducer that has the ADD_ERROR case to add errors and another case to remove the given error.
Then we can map the errors state to props by writing:
export default connect(
state => ({
errors: state.errors,
})
)(App);
where App is a React component.
Tell the Version of React Running at Runtime in the Browser
We can get the React.version property to get the version of React running in the browser.
There’s also the:
npm view react version
npm view react-native version
to get the React version.
require(‘React’).version also works.
Remove the /#/ in the Browser with React Router
To remove the hash sign from the URL with React Roytee, we can use the BrowserRouter as the route root tag,.
For instance, we can write:
import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render ((
<BrowserRouter>
{//...}
<BrowserRouter>
), document.body);
We also need to rewrite the URLs to redirect to index.html so we won’t get errors when loading or refreshing the page:
# Setting up apache options
AddDefaultCharset utf-8
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine on
# Defining the rewrite rules
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.html
This config is for Apache servers.
Render React Components Separated by a Comma by Using map and reduce
We can render React components with map and join by mapping the items to components.
Then we can use reduce to put commas between the components.
For instance, we can write:
class CommaList extends React.Component {
render() {
<div>
{this.props.data
.map(t => <span>{t}</span>)
.reduce((combined, curr) => [combined, ', ', curr])}
</div>
}
}
We get the data prop, which is an array.
Then we call map to map them to components.
And then we call reduce to add commas between the components that are already joined with commas, which is stored in combined and the new component stored in curr .
Conclusion
We can detect situations when the users leave the page in React Router.
We can combine components in an array separated by commas with reduce.
Also, we can dispatch actions when errors occur with Redux.